package com.sms.riskservice.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sms.common.result.Result;
import com.sms.common.result.ResultCode;
import com.sms.riskservice.entity.SmsBlacklist;
import com.sms.riskservice.entity.SmsUserLocation;
import com.sms.riskservice.entity.SmsWhitelist;
import com.sms.riskservice.mapper.SmsBlacklistMapper;
import com.sms.riskservice.mapper.SmsUserLocationMapper;
import com.sms.riskservice.mapper.SmsWhitelistMapper;
import com.sms.riskservice.service.SmsRiskService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class SmsRiskServiceImpl extends ServiceImpl<SmsBlacklistMapper, SmsBlacklist> implements SmsRiskService {
    
    @Autowired
    private SmsBlacklistMapper smsBlacklistMapper;
    
    @Autowired
    private SmsWhitelistMapper smsWhitelistMapper;
    
    @Autowired
    private SmsUserLocationMapper smsUserLocationMapper;
    
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    @Override
    public boolean isInBlacklist(String phoneNumber) {
        if (StrUtil.isBlank(phoneNumber)) {
            return false;
        }
        
        // 先检查白名单
        if (isInWhitelist(phoneNumber)) {
            return false;
        }
        
        // 检查黑名单
        QueryWrapper<SmsBlacklist> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phone_number", phoneNumber)
                   .eq("status", 1); // 黑名单中
        return smsBlacklistMapper.selectCount(queryWrapper) > 0;
    }
    
    @Override
    public boolean isRateLimitExceeded(String phoneNumber) {
        if (StrUtil.isBlank(phoneNumber)) {
            return false;
        }
        
        // 白名单用户不受频率限制
        if (isInWhitelist(phoneNumber)) {
            return false;
        }
        
        String key = "sms:rate_limit:" + phoneNumber;
        String count = (String) redisTemplate.opsForValue().get(key);
        
        if (count == null) {
            // 第一次发送，设置计数器和过期时间
            redisTemplate.opsForValue().set(key, "1", 1, TimeUnit.HOURS);
            return false;
        }
        
        int currentCount = Integer.parseInt(count);
        if (currentCount >= 10) { // 每小时最多10条
            return true;
        }
        
        // 增加计数
        redisTemplate.opsForValue().increment(key);
        return false;
    }
    
    @Override
    public boolean isUserBlocked(String phoneNumber) {
        if (StrUtil.isBlank(phoneNumber)) {
            return false;
        }
        
        // 白名单用户不受拦截
        if (isInWhitelist(phoneNumber)) {
            return false;
        }
        
        // 检查用户是否被系统拦截
        String key = "sms:user_blocked:" + phoneNumber;
        return Boolean.TRUE.equals(redisTemplate.hasKey(key));
    }
    
    @Override
    public boolean isLocationSuspicious(String phoneNumber) {
        if (StrUtil.isBlank(phoneNumber)) {
            return false;
        }
        
        // 白名单用户不检查位置
        if (isInWhitelist(phoneNumber)) {
            return false;
        }
        
        // 检查用户位置信息
        QueryWrapper<SmsUserLocation> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phone_number", phoneNumber);
        SmsUserLocation location = smsUserLocationMapper.selectOne(queryWrapper);
        
        if (location == null) {
            return false; // 没有位置信息，不拦截
        }
        
        // 这里可以添加更复杂的位置检查逻辑
        // 比如检查是否在异常地区，或者位置变化是否合理
        return false;
    }
    
    @Override
    @Transactional
    public Result<String> addToBlacklist(String phoneNumber, Long userId, Integer blacklistType, String reason, Long operatorId) {
        if (StrUtil.isBlank(phoneNumber)) {
            return Result.error(ResultCode.PARAM_ERROR, "手机号不能为空");
        }
        
        // 检查是否已在黑名单中
        if (isInBlacklist(phoneNumber)) {
            return Result.error(ResultCode.PARAM_ERROR, "手机号已在黑名单中");
        }
        
        SmsBlacklist blacklist = new SmsBlacklist();
        blacklist.setPhoneNumber(phoneNumber);
        blacklist.setUserId(userId);
        blacklist.setBlacklistType(blacklistType);
        blacklist.setBlacklistReason(reason);
        blacklist.setBlacklistUserId(operatorId);
        blacklist.setBlacklistTime(LocalDateTime.now());
        blacklist.setStatus(1); // 黑名单中
        
        smsBlacklistMapper.insert(blacklist);
        
        log.info("手机号 {} 已添加到黑名单，原因: {}", phoneNumber, reason);
        return Result.success("添加黑名单成功");
    }
    
    @Override
    @Transactional
    public Result<String> removeFromBlacklist(String phoneNumber, Long operatorId) {
        if (StrUtil.isBlank(phoneNumber)) {
            return Result.error(ResultCode.PARAM_ERROR, "手机号不能为空");
        }
        
        QueryWrapper<SmsBlacklist> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phone_number", phoneNumber)
                   .eq("status", 1);
        
        SmsBlacklist blacklist = smsBlacklistMapper.selectOne(queryWrapper);
        if (blacklist == null) {
            return Result.error(ResultCode.PARAM_ERROR, "手机号不在黑名单中");
        }
        
        blacklist.setStatus(0); // 已解除
        blacklist.setReleaseTime(LocalDateTime.now());
        smsBlacklistMapper.updateById(blacklist);
        
        log.info("手机号 {} 已从黑名单中移除", phoneNumber);
        return Result.success("移除黑名单成功");
    }
    
    @Override
    @Transactional
    public Result<String> addToWhitelist(String phoneNumber, Long userId, Integer whitelistType, String reason, Long operatorId) {
        if (StrUtil.isBlank(phoneNumber)) {
            return Result.error(ResultCode.PARAM_ERROR, "手机号不能为空");
        }
        
        // 检查是否已在白名单中
        if (isInWhitelist(phoneNumber)) {
            return Result.error(ResultCode.PARAM_ERROR, "手机号已在白名单中");
        }
        
        SmsWhitelist whitelist = new SmsWhitelist();
        whitelist.setPhoneNumber(phoneNumber);
        whitelist.setUserId(userId);
        whitelist.setWhitelistType(whitelistType);
        whitelist.setWhitelistReason(reason);
        whitelist.setOperatorId(operatorId);
        whitelist.setWhitelistTime(LocalDateTime.now());
        whitelist.setExpireTime(LocalDateTime.now().plusDays(30)); // 30天有效期
        whitelist.setStatus(1); // 有效
        
        smsWhitelistMapper.insert(whitelist);
        
        log.info("手机号 {} 已添加到白名单，原因: {}", phoneNumber, reason);
        return Result.success("添加白名单成功");
    }
    
    @Override
    @Transactional
    public Result<String> removeFromWhitelist(String phoneNumber, Long operatorId) {
        if (StrUtil.isBlank(phoneNumber)) {
            return Result.error(ResultCode.PARAM_ERROR, "手机号不能为空");
        }
        
        QueryWrapper<SmsWhitelist> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phone_number", phoneNumber)
                   .eq("status", 1);
        
        SmsWhitelist whitelist = smsWhitelistMapper.selectOne(queryWrapper);
        if (whitelist == null) {
            return Result.error(ResultCode.PARAM_ERROR, "手机号不在白名单中");
        }
        
        whitelist.setStatus(0); // 已过期
        smsWhitelistMapper.updateById(whitelist);
        
        log.info("手机号 {} 已从白名单中移除", phoneNumber);
        return Result.success("移除白名单成功");
    }
    
    @Override
    @Transactional
    public Result<String> updateUserLocation(String phoneNumber, String province, String city, String district, 
                                           String address, Double longitude, Double latitude, String ipAddress) {
        if (StrUtil.isBlank(phoneNumber)) {
            return Result.error(ResultCode.PARAM_ERROR, "手机号不能为空");
        }
        
        QueryWrapper<SmsUserLocation> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phone_number", phoneNumber);
        
        SmsUserLocation location = smsUserLocationMapper.selectOne(queryWrapper);
        
        if (location == null) {
            // 新增位置信息
            location = new SmsUserLocation();
            location.setPhoneNumber(phoneNumber);
        }
        
        location.setProvince(province);
        location.setCity(city);
        location.setDistrict(district);
        location.setAddress(address);
        location.setLongitude(longitude);
        location.setLatitude(latitude);
        location.setIpAddress(ipAddress);
        location.setLastUpdateTime(LocalDateTime.now());
        
        if (location.getId() == null) {
            smsUserLocationMapper.insert(location);
        } else {
            smsUserLocationMapper.updateById(location);
        }
        
        return Result.success("更新位置信息成功");
    }
    
    /**
     * 检查手机号是否在白名单中
     */
    private boolean isInWhitelist(String phoneNumber) {
        QueryWrapper<SmsWhitelist> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phone_number", phoneNumber)
                   .eq("status", 1)
                   .gt("expire_time", LocalDateTime.now()); // 未过期
        return smsWhitelistMapper.selectCount(queryWrapper) > 0;
    }
} 